'use strict'
const { app } = require('electron')
const { Service } = require('ee-core')
const fs = require('fs-extra')
const { console } = require('inspector')
const path = require('path')
const supportedExtensions = ['.html', '.js', '.txt', '.json', '.vue']

class AsyncQueue {
    queue = [];
    runningTasks = 0;
    constructor(maxLength = 10, retryLimit = 3) {
        this.maxLength = maxLength
        this.retryLimit = retryLimit
    }

    async enqueue (asyncFunction) {
        return new Promise(async (resolve, reject) => {
            const task = { asyncFunction, retries: 0, resolve, reject }

            this.queue.push(task)

            if (this.runningTasks >= this.maxLength) {
                return
            }
            // 启动异步任务
            this.processQueue()
        })
    }

    async processQueue () {
        if (!this.queue.length || this.runningTasks >= this.maxLength) {
            return
        }
        const tasksToProcess = this.queue.splice(0, this.maxLength - this.runningTasks)
        this.runningTasks += tasksToProcess.length

        await Promise.all(
            tasksToProcess.map(async ({ asyncFunction, retries, resolve, reject }) => {
                try {
                    const result = await asyncFunction()
                    resolve(result)
                } catch (error) {
                    if (retries < this.retryLimit) {
                        this.queue.push({ asyncFunction, retries: retries + 1, resolve, reject })
                    } else {
                        reject(error)
                    }
                } finally {
                    this.runningTasks--
                }
            })
        )
        await this.processQueue()
    }
}
/**
 * 示例服务（service层为单例）
 * @class
 */
class ExampleService extends Service {

    constructor(ctx) {
        super(ctx)
    }
    /**
     * 读取文件
     */
    async readFile (args) {
        // 获取用户数据目录
        const userDataPath = app.getPath('userData')
        const { dict } = args
        let dictPath = dict === '天津风控' ? path.join(userDataPath, 'desensitizationDict.txt') : path.join(userDataPath, 'desensitizationDict_ytjl.txt')
        try {
            const content = fs.readFileSync(dictPath, 'utf-8')
            return {
                dictPath,
                content
            }
        } catch (error) {
            if (error.code === 'ENOENT') {
                const data = [{
                    "plaintext": "敏感词",
                    "ciphertext": "替换词"
                }]
                const jsonString = JSON.stringify(data, null, 2)
                fs.writeFileSync(dictPath, jsonString, 'utf-8')
                const content = fs.readFileSync(dictPath, 'utf-8')
                return {
                    dictPath,
                    content
                }
            }
        }
    }
    /**
     * desensitization
     */
    async desensitization (args) {
        // 处理文件类型
        const { targetFilePath, resultFilePath, replaceRules } = args
        const replaceRulesParsed = JSON.parse(replaceRules || '[]')
        const files = await findTargetFiles(targetFilePath)
        const concurrentLimit = 5
        const queue = new AsyncQueue(concurrentLimit)
        const results = []
        let processed = 0
        let successful = 0
        const tasks = files.map(file => async () => {
            const result = await processFile(file.path, replaceRulesParsed)
            processed++
            if (result.success) {
                successful++
                console.log(`✓ 处理成功: ${file.path} (${result.changes} 处更改)`)
            } else {
                console.error(`✗ 处理失败: ${file.path} - ${result.error}`)
            }
            // 更新进度
            console.log(`进度: ${processed}/${files.length} (${Math.round((processed / files.length) * 100)}%)`)
            return result
        })
        // 将任务加入队列
        console.log(`开始处理文件 (并发数: ${concurrentLimit})...`)

        for (const task of tasks) {
            results.push(await queue.enqueue(task))
        }

        // 输出统计信息
        console.log('\n处理完成!')
        console.log(`总文件数: ${files.length}`)
        console.log(`成功处理: ${successful}`)
        console.log(`失败: ${files.length - successful}`)

        const totalChanges = results
            .filter(r => r.success)
            .reduce((sum, r) => sum + (r.changes || 0), 0)
        console.log(`总替换次数: ${totalChanges}`)
        return {
            success: true,
            totalFiles: files.length,
            successful,
            failed: files.length - successful,
            totalChanges
        }
    }
}
/**
 * 递归遍历目录并找到目标文件
 */
async function findTargetFiles (dirPath) {
    const results = []

    try {
        const items = fs.readdirSync(dirPath)

        for (const item of items) {
            const fullPath = path.join(dirPath, item)
            const stat = fs.statSync(fullPath)

            if (stat.isDirectory()) {
                // 递归遍历子目录
                const subResults = await findTargetFiles(fullPath)
                results.push(...subResults)
            } else if (stat.isFile()) {
                // 检查文件扩展名
                const ext = path.extname(item).toLowerCase()
                if (supportedExtensions.includes(ext)) {
                    results.push({
                        path: fullPath,
                        name: item,
                        extension: ext,
                        size: stat.size
                    })
                }
            }
        }
    } catch (error) {
        console.error(`遍历目录失败: ${dirPath}`, error)
    }

    return results
}
/**
 * 读取文件内容并应用替换规则
 */
async function processFile (filePath, rules) {
    try {
        // 读取文件内容
        const content = fs.readFileSync(filePath, 'utf8')

        // 应用所有替换规则
        let newContent = content
        for (const rule of rules) {
            const regex = new RegExp(rule.from, 'g')
            newContent = newContent.replace(regex, rule.to)
        }

        // 如果内容有变化，则写回文件
        if (newContent !== content) {
            fs.writeFileSync(filePath, newContent, 'utf8')
            return {
                success: true,
                path: filePath,
                changes: countChanges(content, newContent, rules)
            }
        }

        return {
            success: true,
            path: filePath,
            changes: 0,
            message: '内容无变化'
        }
    } catch (error) {
        return {
            success: false,
            path: filePath,
            error: error.message
        }
    }
}
module.exports = ExampleService